/* 
 * Created on 2007-4-23
 * Last modified on 2007-4-23
 * Powered by YeQiangWei.com
 */
package com.yeqiangwei.image;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;

import org.apache.log4j.Logger;

import com.yeqiangwei.image.gif.AnimatedGifEncoder;
import com.yeqiangwei.image.gif.GifDecoder;
import com.yeqiangwei.util.ArithHelper;
import com.yeqiangwei.util.Validator;

/**
 * 
 * @author yeqiangwei
 */
public class ImageGif extends ImageOperate{
	
	private static final Logger logger = Logger.getLogger(ImageGif.class);

	@Override
	public boolean clip(BufferedInputStream bis, String filePathAndName, int w, int h, int x, int y, int x_w, int y_h) {
		boolean bea = false;
		GifDecoder gifDecoder = new GifDecoder();
		try {
			gifDecoder.read(bis); //读取GIF文件
			int n = gifDecoder.getFrameCount(); //读取GIF帧数
			List<BufferedImage> imgList = new ArrayList<BufferedImage>();
			List<Integer> delays = new ArrayList<Integer>();
			for (int i = 0; i < n; i++) {
				BufferedImage frame = gifDecoder.getFrame(i); // frame i
				int t = gifDecoder.getDelay(i); //GIF帧数间隔时间
				imgList.add(frame);
				delays.add(t);
			}
			try {
				this.gif(imgList,delays, null, filePathAndName,w,h,x,y,x_w,y_h);
				bea = true;
			} catch (Exception e) {
				logger.error(e.toString());
			}
			bis.close();
		} catch (IOException e) {
			logger.error(e.toString());
		}		
		return bea;
	}

 
	public boolean incise(File file, String filePathAndName, int w, int h, int x, int y, int x_w, int y_h) {
		boolean bea = false;
		try {
			FileInputStream fis = new FileInputStream(file);
			BufferedInputStream bis = new BufferedInputStream (fis);
			this.clip(bis,filePathAndName,w,h,x,y,x_w,y_h);
			bis.close();
			fis.close();
		} catch (IOException e) {
			logger.error(e.toString());
		}		
		return bea;
	}
	
	/**
	 * 
	 * @param bi
	 * @param delays
	 * @param filePathAndName
	 * @param wimgs 合成图片
	 * @param w
	 * @param h
	 * @param x
	 * @param y
	 * @param x_w
	 * @param y_h
	 * @throws IOException
	 */
	private void gif(List<BufferedImage> bi, List<Integer> delays, Image[] wimgs, String filePathAndName,
			 int w, int h, int x, int y, int x_w, int y_h) throws IOException{
		
		if(!Validator.isEmpty(bi)
				&&!Validator.isEmpty(delays)
				&&bi.size()==delays.size())
		{
			FileOutputStream out = new FileOutputStream(filePathAndName);
			AnimatedGifEncoder gifEncoder = new AnimatedGifEncoder();
			gifEncoder.start(out);
			for(int i=0; i<bi.size(); i++){
				java.awt.image.BufferedImage tag = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB); 

				BufferedImage img = bi.get(i);
				Graphics2D g2d = tag.createGraphics();
				
				//g2d.setBackground(Color.BLUE);
				//g2d.drawString("yeqiangwei.com", 50, 100);

				if(x!=-1 && y!=-1 && x_w!=-1 && y_h!=-1){
					g2d.drawImage(img, 0, 0, w, h, x, y, x_w, y_h, null);
				}else if(x_w!=-1 && y_h!=-1){
					g2d.drawImage(img, 0, 0, w, h, 0, 0, x_w, y_h, null);
				}else{
					g2d.drawImage(img, 0, 0, w, h, null);
				}
				if(!Validator.isEmpty(wimgs)){
					for(int wi=0; wi<wimgs.length; wi++){
						Image wimg = wimgs[wi];
						int w1 = wimg.getWidth(null); /* 得到水图1宽 */  
				        int h1 = wimg.getHeight(null); /* 得到水图1高 */
				        if(w1!=-1&&h1!=-1){
				        	g2d.drawImage(wimg,w-w1-12,h-h1-10,w1,h1,null);
				        }
					}
				}
				/*
				Graphics g = tag.getGraphics();
				if(x!=-1 && y!=-1 && x_w!=-1 && y_h!=-1){
					g.drawImage(img, 0, 0, w, h, x, y, x_w, y_h, null);
				}else if(x_w!=-1 && y_h!=-1){
					g.drawImage(img, 0, 0, w, h, 0, 0, x_w, y_h, null);
				}else{
					g.drawImage(img, 0, 0, w, h, null);
				}
				*/
	            gifEncoder.setDelay(delays.get(i)); // 1 frame per sec
	            gifEncoder.setRepeat(0);
				gifEncoder.setQuality(0);
	            gifEncoder.addFrame(tag);
	            g2d.dispose();
			}
			gifEncoder.finish();
			out.close();
		}else{
			logger.error("GIF 文件错误！");
		}
	}

	@Override
	public boolean narrowOrEnlarge(String opath, String npath, int w, int h) {
    	if(Validator.isEmpty(opath)||Validator.isEmpty(npath)){
    		return false;
    	}
    	GifDecoder gifDecoder = new GifDecoder();
    	boolean bea = false;
        final int ow = w; //指定的尺寸不在计算中变化
        final int oh = h; //指定的尺寸不在计算中变化
        double wd = 0;
        double hd = 0;
        String ws = "", hs = "";
		try {
			Image img = new ImageIcon(opath).getImage();
			int width = img.getWidth(null); //得到源图宽  
	        int height = img.getHeight(null); //得到源图长
	        if(width==-1||height==-1){
	        	return false;
	        }
            //同时指定宽高
            if(w > width){
                w = width;
            }
            if(h > height){
                h = height;
            }  
            if(w>0 && h==0){
                // 计算出宽度的缩放比例
                wd = ArithHelper.div(w, width, 10);     
                hd = ArithHelper.mul(wd, height);
                hd = ArithHelper.round(hd,0); //四舍五入保留小数点0位
                hs = String.valueOf(hd).substring(0, String.valueOf(hd).indexOf("."));
                h = Integer.parseInt(hs) ; //按比例缩小高度
                if(h<1){
                    h = height;
                }
            }
            else if(h > 0 && h < height && w==0){
            	hd = ArithHelper.div(h,height,10);
                wd = ArithHelper.mul(hd,width);
                wd = ArithHelper.round(wd,0); //四舍五入保留小数点0位
                ws = String.valueOf(wd).substring(0, String.valueOf(wd).indexOf("."));
                w = Integer.parseInt(ws) ; //按比例缩小高度
                if(w<1){
                    w = width;
                }
            }
            else if(w>0 && h>0){
            	//计算出宽度的缩放比例
                wd = ArithHelper.div(ow, width, 10);     
                hd = ArithHelper.mul(wd, height);
                hd = ArithHelper.round(hd,0); //四舍五入保留小数点0位
                hs = String.valueOf(hd).substring(0, String.valueOf(hd).indexOf("."));
                h = Integer.parseInt(hs) ; //按比例缩小高度
                if(h<1){
                    h = height;
                }
                if(h<oh){//如果指定小图的比例不符合原图的比例
                	h = oh;
                	hd = ArithHelper.div(oh, height, 10);     
                    wd = ArithHelper.mul(hd, width);
                    wd = ArithHelper.round(wd,0); //四舍五入保留小数点0位
                    ws = String.valueOf(wd).substring(0, String.valueOf(wd).indexOf("."));
                    w = Integer.parseInt(ws) ; //按比例缩小高度
                    if(w<1){
                        w = width;
                    }
                }
            }
			FileInputStream fis = new FileInputStream(new File(opath));
			BufferedInputStream bis = new BufferedInputStream (fis);
			gifDecoder.read(bis); //读取GIF文件
			int n = gifDecoder.getFrameCount(); //读取GIF帧数
			List<BufferedImage> imgList = new ArrayList<BufferedImage>();
			List<Integer> delays = new ArrayList<Integer>();
			for (int i = 0; i < n; i++) {
				BufferedImage frame = gifDecoder.getFrame(i); // frame i
				int t = gifDecoder.getDelay(i); //GIF帧数间隔时间
				imgList.add(frame);
				delays.add(t);
			}
			try {
				this.gif(imgList,delays, null, npath,w,h,-1,-1,-1,-1);
				bea = true;
				fis.close();
				bis.close();
			} catch (Exception e) {
				logger.error(e.toString());
			}
		} catch (IOException e) {
			logger.debug(e.toString());
		}
		return bea;
	}

	@Override
	public boolean watermark(String opath, String npath, String wpath) {
		Image image = new ImageIcon(opath).getImage();
		return this.watermark(image,opath,npath,wpath);
	}

	@Override
	public boolean watermark(String opath, String npath, String wpath, int minwidth, int minheight) {
		Image image = new ImageIcon(opath).getImage();
		if(image.getWidth(null)<minwidth||image.getHeight(null)<minheight){
			return false;
		}else{
			return this.watermark(image,opath,npath,wpath);
		}
	}

	private boolean watermark(Image image, String opath, String npath, String wpath) {
		boolean bea = false;
		try {
			//Image src = new ImageIcon(opath).getImage();
			int w = image.getWidth(null); /* 得到源图宽 */  
	        int h = image.getHeight(null); /* 得到源图高 */
	        if(w==-1||h==-1){
	        	return false;
	        }
	        BufferedImage tag = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);  
	        tag.getGraphics().drawImage(image,0,0,w,h,null);
            GifDecoder gifDecoder = new GifDecoder();
            FileInputStream fis = new FileInputStream(new File(opath));
			BufferedInputStream bis = new BufferedInputStream (fis);
			gifDecoder.read(bis); //读取GIF文件
			int n = gifDecoder.getFrameCount(); //读取GIF帧数
			List<BufferedImage> imgList = new ArrayList<BufferedImage>();
			List<Integer> delays = new ArrayList<Integer>();
			for (int i = 0; i < n; i++) {
				BufferedImage frame = gifDecoder.getFrame(i); // frame i
				int t = gifDecoder.getDelay(i); //GIF帧数间隔时间
				imgList.add(frame);
				delays.add(t);
			}
			try {
				Image[] wimgs = new Image[1];
				wimgs[0] = new ImageIcon(wpath).getImage();//构造Image对象 
				this.gif(imgList,delays, wimgs, npath, w, h, -1, -1, -1, -1);
				bea = true;
			} catch (Exception e) {
				logger.error(e.toString());
			}
            bis.close();
            fis.close();   
		} catch (IOException e) {
			logger.error(e.toString());
		} 
		return bea;
	}
}
